{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e16cf9c6",
   "metadata": {},
   "source": [
    "---------\n",
    "* Author:Xiao yang\n",
    "* 时间：1209-week15\n",
    "\n",
    "*  资源:\n",
    "\n",
    "> 1. [zhichao博客](https://www.cnblogs.com/xuzhichao/p/11570285.html)\n",
    "> 2. [python 官网资料](https://docs.python.org/3/tutorial/controlflow.html#defining-functions)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9110d76a",
   "metadata": {},
   "source": [
    "# 上周回顾\n",
    "> 1. 函数的定义 ： def\n",
    "> 2. 函数名的定义规则-->变量名一样的规则\n",
    "> 3. 调用函数的方式 ： func_name(参数)\n",
    "> 4. 参数：\n",
    ">> 1. 形式参数（定义函数）\n",
    ">> 2. 实际参数（调用函数）\n",
    ">> 3. 有多个参数时：\n",
    ">>> 1. 关键字参数\n",
    ">>> 2. 位置参数（调用函数时）---> 关键字参数要均放在末尾（多个不考虑顺序）\n",
    ">>> 3. 默认参数（定义函数时）---> 默认参数均放在末尾（多个不考虑顺序）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f00477c5",
   "metadata": {},
   "source": [
    "# 本周知识点\n",
    "> 1. 函数的返回值\n",
    "> 2. 函数的输入参数类型\n",
    "> 3. 函数的返回参数类型\n",
    "> 4. 模块与函数的关系\n",
    "> 5. 模块的概念\n",
    "> 6. 如何创建一个模块，并且调用自己定义的模块\n",
    ">> 1. 调用模块\n",
    ">> 2. 调用模块中的函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2181fb05",
   "metadata": {},
   "source": [
    "## 函数的返回值\n",
    "> 1. 返回值关键字： return\n",
    "***\n",
    "f(x) = ax + c\n",
    "f(2) = ax + c\n",
    "***\n",
    ">> 1. 函数一定要有返回值（无论是什么编程语言）\n",
    ">> 2. 在其他的编程语言中（如c语言，Java等），返回值一定要写，不写会报错！ ；对于python（更高级的语言），返回值如果不写，给定默认值 None\n",
    ">> 3. 返回值一般为函数体运行的结果（return）  （函数返回值实践1）； 也可以自定义函数返回值（实践2）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "fd8a0ab6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 函数返回值实践1\n",
    "def get_formatted_name(first_name,last_name):\n",
    "    \"\"\"返回整洁的姓名\"\"\"\n",
    "    full_name = first_name + ' '+ last_name\n",
    "#     print(full_name)\n",
    "    return full_name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "615d5bc4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Li Hua\n"
     ]
    }
   ],
   "source": [
    "print(get_formatted_name(\"Li\",\"Hua\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "600ed57f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 实践2\n",
    "def log_in(username,password):\n",
    "    \"\"\"验证登录信息\"\"\"\n",
    "    if username == \"Lihua\" and password == 123456:\n",
    "        return 1\n",
    "    else:\n",
    "        return 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f52d939a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "log_in(\"Lihua\",12345)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c1dd66d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 404：找不到网页\n",
    "# 500：服务端有bug"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0566f228",
   "metadata": {},
   "source": [
    "## 函数的输入参数类型\n",
    "> 1. 函数可以输入复杂的参数\n",
    ">> 1. 函数可以输入复杂的参数（例如列表、字典、集合、元组等）：\n",
    ">>> 1. 函数参数为列表\n",
    ">>> 2.函数参数为字典\n",
    ">> 2. 函数可以输入不确定个数的参数：\n",
    ">>> 1. *args\n",
    ">>> 2. ** kwargs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6ac41999",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test_A(names):\n",
    "    \"\"\"测试函数参数输入为列表\"\"\"\n",
    "    return(names)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "00d936e6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Lihua', 'Xiaofeng', 'Ziqi']"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_A([\"Lihua\",\"Xiaofeng\",\"Ziqi\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "7b2d7c90",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test_B(person):\n",
    "    \"\"\"测试函数参数输入为字典\"\"\"\n",
    "    return(person)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "e7a73008",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'stud_id': 210001, 'age': 18, 'job': 'studenet'}"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_B({\"stud_id\":210001,\"age\":18,\"job\":\"studenet\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68578f0f",
   "metadata": {},
   "source": [
    "> 2. 函数可以输入不确定个数的参数：\n",
    ">> 1. args\n",
    ">>> 1. args 可以接受多个数据（单值）\n",
    ">>> 2. args 将多个数据存在一个**元组**当中，实际还是一个变量\n",
    ">> 2. kwargs\n",
    ">>> 1. kwargs 可以接受多个数据(键值对)==> 关键字参数\n",
    ">>> 2. kwargs 将多个 键值对 的数据存放在一个**字典**中，实际上还是一个变量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "e17a77a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# *args\n",
    "def food_ingred(food,*ingreds):\n",
    "    \"\"\"食物配料单\"\"\"\n",
    "    return food,ingreds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "44a447f1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('pizza', ('mushroom', 'green peppers', 'extra cheese'))"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "food_ingred(\"pizza\",\"mushroom\",\"green peppers\",\"extra cheese\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "f83d047b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# **kwargs\n",
    "def person(stud_name,**stud_course):\n",
    "    \"\"\"学生个人信息完善表\"\"\"\n",
    "    return stud_name,stud_course"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "9f0fd3b9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('Lihua', {'course_星期一': 'API', 'course_星期二': 'APP原型设计'})"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "person(\"Lihua\",course_星期一=\"API\",course_星期二=\"APP原型设计\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2853efbe",
   "metadata": {},
   "outputs": [],
   "source": [
    "def func_name(arg1,arg2,*arg,**kwargs):\n",
    "    \"\"\"考虑比较周到的函数参数\"\"\"\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eea61a0a",
   "metadata": {},
   "source": [
    "## 函数的输出（返回值）参数的类型\n",
    "\n",
    "> 1. 在编程语言中，函数的返回值只能是一个值\n",
    "> 2. 返回值可以是 字符串、数值、列表、字典等数据（单一值）\n",
    "> 3. python可以输出多个返回值，结果会用一个元组进行封装并返回。（本质不违背函数的定义）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "80e5383b",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test1_return():\n",
    "    \"\"\"测试返回值return为字符串\"\"\"\n",
    "    return \"你好\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "28f4701d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好'"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test1_return()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "0407ff05",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test2_return():\n",
    "    \"\"\"测试返回值return为\"\"\"\n",
    "    return 12345"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "7f956091",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12345"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test2_return()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "ec0fa8c3",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test3_return():\n",
    "    \"\"\"测试返回值return为列表\"\"\"\n",
    "    return ['Lihua', 'Alex', 'Ziqi']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "a920f623",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Lihua', 'Alex', 'Ziqi']"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test3_return()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "5948bde1",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test4_return():\n",
    "    \"\"\"测试返回值return为字典\"\"\"\n",
    "    return {'stud_id': 210001, 'age': 18, 'Job': 'student'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "58f7266f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'stud_id': 210001, 'age': 18, 'Job': 'student'}"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test4_return()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "250bbd25",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ******** return 后面写多个值，将会返回一个元组（一个值，不违背函数在编程思维中的定义）\n",
    "def test5_return():\n",
    "    \"\"\"测试返回值return 为 多个值的情况\"\"\"\n",
    "    return 18,\"Lihua\",['Lihua', 'Alex', 'Ziqi'],{'stud_id': 210001, 'age': 18, 'Job': 'student'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "78e3a2aa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(18,\n",
       " 'Lihua',\n",
       " ['Lihua', 'Alex', 'Ziqi'],\n",
       " {'stud_id': 210001, 'age': 18, 'Job': 'student'})"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test5_return()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "13c9d928",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test6_return():\n",
    "    \"\"\"测试返回值return 为 多个值的情况\"\"\"\n",
    "    return 88,89,90,90\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "dfbcd28a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(88, 89, 90, 90)"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test6_return()\n",
    "# python 把多个值 封装成了一个值"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77b2e7f8",
   "metadata": {},
   "source": [
    "## 函数模块\n",
    "\n",
    "> 1. 使用模块可以隐藏函数的源代码\n",
    "> 2. 使用的人不需要会底层代码（只需要会使用模块即可）\n",
    "> 3. 模块的使用的方法：\n",
    ">> 1. import 模块名\n",
    ">>> * 使用： 模块名.函数名()\n",
    ">> 2. from 模块名 import 函数名\n",
    ">>> * 使用： 函数名()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "42cb68a6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ad7f2a1b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "time.struct_time(tm_year=2021, tm_mon=12, tm_mday=14, tm_hour=17, tm_min=43, tm_sec=10, tm_wday=1, tm_yday=348, tm_isdst=0)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "time.localtime()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6930facb",
   "metadata": {},
   "outputs": [],
   "source": [
    "from time import localtime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f11f43e8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "time.struct_time(tm_year=2021, tm_mon=12, tm_mday=14, tm_hour=17, tm_min=43, tm_sec=49, tm_wday=1, tm_yday=348, tm_isdst=0)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "localtime()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2878794",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c50a7413",
   "metadata": {},
   "outputs": [],
   "source": [
    "import study"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "e2c21aa1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a', 'e', 'i', 'o'}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 1.  函数的调用\n",
    "study.search4vowels(\"hello xiaoyang\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "90697a9b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 函数的定义\n",
    "def search4vowels(word):\n",
    "    \"\"\"找出文本中出现的元音字母\"\"\"\n",
    "    return set(\"aeiou\") & set(word)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "8a5327c9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a', 'e', 'i', 'o'}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 函数的应用\n",
    "search4vowels(\"hello xiaoyang\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d1e90af8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function news_链接 in module study:\n",
      "\n",
      "news_链接(url, 新闻分类, page)\n",
      "    抓取学校新闻的所有页面链接\n",
      "    url:学校网站的域名链接\n",
      "    新闻分类:学校新闻的分类英文简称\n",
      "    page:你想要抓取的页面尾页\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 2. 抓取数据\n",
    "help(study.news_链接)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "2dd368bc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['https://www.nfu.edu.cn/xydt/index.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index1.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index2.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index3.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index4.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index5.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index6.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index7.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index8.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index9.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index10.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index11.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index12.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index13.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index14.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index15.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index16.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index17.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index18.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index19.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index20.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index21.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index22.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index23.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index24.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index25.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index26.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index27.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index28.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index29.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index30.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index31.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index32.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index33.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index34.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index35.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index36.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index37.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index38.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index39.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index40.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index41.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index42.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index43.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index44.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index45.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index46.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index47.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index48.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index49.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index50.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index51.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index52.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index53.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index54.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index55.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index56.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index57.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index58.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index59.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index60.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index61.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index62.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index63.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index64.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index65.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index66.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index67.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index68.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index69.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index70.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index71.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index72.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index73.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index74.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index75.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index76.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index77.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index78.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index79.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index80.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index81.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index82.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index83.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index84.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index85.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index86.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index87.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index88.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index89.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index90.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index91.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index92.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index93.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index94.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index95.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index96.htm',\n",
       " 'https://www.nfu.edu.cn/xydt/index97.htm']"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "study.news_链接('https://www.nfu.edu.cn/','xydt','98') # 可更改数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "29f47143",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['https://www.nfu.edu.cn/tzgg/index.htmtzgg/index.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index1.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index2.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index3.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index4.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index5.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index6.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index7.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index8.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index9.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index10.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index11.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index12.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index13.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index14.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index15.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index16.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index17.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index18.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index19.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index20.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index21.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index22.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index23.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index24.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index25.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index26.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index27.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index28.htm',\n",
       " 'https://www.nfu.edu.cn/tzgg/index.htmtzgg/index29.htm']"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "study.news_链接('https://www.nfu.edu.cn/tzgg/index.htm','tzgg','30')\n",
    "#   奇怪 出现数据连接 但是 搜索网页报错404\n",
    "# The requested URL /tzgg/index.htmtzgg/index15.htm was not found on this server."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19ada0ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 函数可不可以去调用其他函数\n",
    "# 函数的递归\n",
    "# (老师博客最下面的)[https://www.cnblogs.com/xuzhichao/p/11570285.htmlv]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "488c286c",
   "metadata": {},
   "source": [
    "# 关于递归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "ca948b67",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "5\n",
      "2\n",
      "1\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def calc(n):\n",
    "    print(n)\n",
    "    if int(n/2) == 0:\n",
    "        return n\n",
    "    return calc(int(n/2))\n",
    "\n",
    "calc(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ac70737",
   "metadata": {},
   "source": [
    "* 接触算法后，在解决问题时，最快，最容易理解的解法就是递归\n",
    "* 在算法中遇到可以用递归轻松完成的：\n",
    "> 希尔排序、归并排序、快速排序、反转链表及各种反转问题、二叉树的深度遍历、二叉树的各种题基本可以用、全排列…还有算法步骤里需要用到，太多了，所以，递归非常重要！"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23a7d6e6",
   "metadata": {},
   "source": [
    "***\n",
    "函数：我们已经知道些什么\n",
    "\n",
    "* 函数是命名的代码块。\n",
    "\n",
    "* def关键字用来命名函数，函数代码在def关键字下（相对于def关键字）缩进\n",
    "\n",
    "* Python的三重引号字符串可以用来函数增加多行注释。如果采用这种方式，他们称之为docstring\n",
    "\n",
    "* 函数可以接受任意多个命名参数\n",
    "\n",
    "* return语句允许函数返回任意值（也可以不反回任何值）\n",
    "\n",
    "* 函数注解可以用来描述函数参数的类型\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5c438cb",
   "metadata": {},
   "source": [
    "# 递归的两个过程:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "1025c019",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5 <===1====>\n",
      "4 <===1====>\n",
      "3 <===1====>\n",
      "2 <===1====>\n",
      "1 <===1====>\n",
      "0 <===1====>\n",
      "0 <===2====>\n",
      "1 <===2====>\n",
      "2 <===2====>\n",
      "3 <===2====>\n",
      "4 <===2====>\n",
      "5 <===2====>\n"
     ]
    }
   ],
   "source": [
    "# 首先“递归”包括两个过程：递“去”的过程，“归”回的过程！先从一个简单的递归函数讲起\n",
    "def di_gui(n):\n",
    "    print(n, \"<===1====>\")\n",
    "    if n > 0:\n",
    "        di_gui(n - 1)\n",
    "    print(n, '<===2====>')\n",
    "\n",
    "\n",
    "di_gui(5) # 外部调用后打印的结果是？\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "509a5186",
   "metadata": {},
   "source": [
    "* 递归的执行过程：首先，递归会执行“去”的过程，只需要满足终止条件，就会一直在函数内，带着更新的参数，调用函数自身，注意：到内部调用函数， **以下面的代码不会被执行，而是暂停阻塞；** 此时 随着函数每调用一次自身，还没有触发 返回值和到达终止条件，等同于在原来的基础上不断“向下/向内”开辟新的内存空间，记住，每次调用一次函数，就不是处在同一空间（想象下《盗梦空间》里的情景，梦中梦，都是处于不同的空间）\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "004d3e3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "# 代码解析：\n",
    "digui(5)\n",
    "去的过程：\n",
    "n=5 print(5,\"<===1====>\") 5>0 digui(n-1) => digui(4) 代码在第五行 ，暂定加阻塞\n",
    "n=4 print(4,\"<===1====>\") 4>0 digui(n-1) => digui(3) 代码在第五行 ，暂定加阻塞\n",
    "n=3 print(3,\"<===1====>\") 3>0 digui(n-1) => digui(2) 代码在第五行 ，暂定加阻塞\n",
    "n=2 print(2,\"<===1====>\") 2>0 digui(n-1) => digui(1) 代码在第五行 ，暂定加阻塞\n",
    "n=1 print(1,\"<===1====>\") 1>0 digui(n-1) => digui(0) 代码在第五行 ，暂定加阻塞\n",
    "n=0 print(0,\"<===1====>\") 0>0 digui(n-1) => 不满足条件，执行print(n, \"<===2====>\")\n",
    "\n",
    "'''"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2bb57873",
   "metadata": {},
   "source": [
    "* 什么时候“递”去的过程结束？记住有两种情况:\n",
    "> * 一是：当前这层空间函数全部执行结束（终止条件）;\n",
    "> * 二是：执行到了return 返回值，直接返回。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b023f451",
   "metadata": {},
   "source": [
    "* 重点来理解下，首先是一，看上面的列子，例子中没有return，但是不断的调用后，最终还是停止了，因为最后n=0时，di_gi(0)还是去调用，从上往下执行时，遇到if n>0 它被终止了，走不下去了，表明，自己能到达的这层空间已经全部执行完毕；接下来请原地返回吧，返回到哪里？返回到函数的调用者，好我们返回到 di_gui(0)，把“到内部调用函数” 以下的代码全部执行完；执行完，看代码走到末尾，以为走出了最外层函数？注意了，此时它所处的空间并不是最外层哦，因为之前它被调用就在空间里面，所以回到的是 di_gui(1)的这一层空间，现在才是真正的开始“回”，所以继续把di_gui(1)的这一层空间，“到内部调用函数”以下的代码全部执行完，回到di_gui(2)的这一层空间…直到到达最开始 从外部调用，让参数5进入的最外层空间位置，才走出来！表示《盗梦空间》里，柯布醒了！\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b15186f",
   "metadata": {},
   "source": [
    "# 参考资料---> 递归：[CSDN](https://blog.csdn.net/storyfull/article/details/102671946?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163947686616780261974869%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163947686616780261974869&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-102671946.pc_search_all_es&utm_term=python+%E9%80%92%E5%BD%92&spm=1018.2226.3001.4187)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ffd3b1e6",
   "metadata": {},
   "source": [
    "## 递归特性：\n",
    "\n",
    "> 1.必须有一个明确的结束条件\n",
    "\n",
    "> 2.每次进入更深一层递归时，问题规模相比上次递归应有所减少。\n",
    "\n",
    "> 3.递归效率不高，递归次数过多会导致栈溢出（在计算机中，函数调用是通过栈（stack）这种数据结构实现的，每当进入一个函数调用，栈就会多加一层栈帧，每当函数返回，栈就会减少一层栈帧。由于栈的大小不是无限的，所以，递归调用的次数过多，会导致栈溢出。）"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
